<template>
  <el-container class="register-email-container">
    <el-button class="register-email-container-back" @click="back">
      <i class="el-icon-arrow-left"/>
      返回登录页
    </el-button>
    <el-form ref="form" :model="form" :rules="rules">
      <el-form-item prop="email">
        <el-input v-model="form.email" placeholder="输入注册邮箱">
          <el-button slot="append" :disabled="disabledSendBtn" tabindex="-1" @click="sendVerificationCode">
            {{ sendVerificationCodeBtnContent }}
          </el-button>
        </el-input>
      </el-form-item>
      <el-form-item prop="verificationCode">
        <el-input v-model="form.verificationCode" placeholder="输入验证码"/>
      </el-form-item>
    </el-form>
    <el-button class="register-email-container-verify" type="primary" @click="verify('form')">
      验证
    </el-button>
  </el-container>
</template>

<script>
import emailApiBinder from '@/axios/email';
import { successMsg } from '@/utils/message';
import { isEmail, isNumber } from '@/utils/regexValidate';

const msPerS = 1000;

export default {
  name: 'RegisterEmailComp',
  data() {
    const validateEmail = function (rule, email, callback) {
      if (isEmail(email)) {
        callback();
      } else {
        callback(new Error('输入正确格式的email'));
      }
    };
    const validateNumber = function (rule, email, callback) {
      if (isNumber(email)) {
        callback();
      } else {
        callback(new Error('必须为数字'));
      }
    };
    return {
      form: {
        email: '',
        verificationCode: ''
      },
      rules: {
        email: [
          { required: true, message: '邮箱不能为空', trigger: 'blur' },
          { validator: validateEmail, trigger: 'blur' }
        ],
        verificationCode: [
          { required: true, message: '验证码不能为空', trigger: 'blur' },
          { max: 6, min: 6, message: '验证码必须为6位', trigger: 'blur' },
          // 若用自带的 type: number，则 max和min 无法校验长度
          { validator: validateNumber, trigger: 'blur' }
        ]
      },
      disabledSendBtn: false,
      sendThrottlingTime: 60 * msPerS,
      sendWaitingTime: 0,
      sendWaitingTimer: null
    };
  },
  computed: {
    sendVerificationCodeBtnContent() {
      let content = '获取验证码';
      if (this.sendWaitingTime) {
        content += `（${this.sendWaitingTime / 1000}s）`;
      }
      return content;
    }
  },
  watch: {
    sendVerificationCodeBtnContent() {
      this.disabledSendBtn = Boolean(this.sendWaitingTime);
    }
  },
  created() {
    this.apis = emailApiBinder(this);
  },
  methods: {
    back(){
      this.$router.push('/login');
    },
    async sendVerificationCode() {
      const validated = await new Promise(resolve => {
        this.$refs.form.validateField('email', errorMsg => {
          resolve(!errorMsg);
        });
      });
      if (!validated) {
        return;
      }
      const { email } = this.form;
      const resData = await this.apis.send({ email });
      if (resData.success) {
        const expireMinutes = (resData.data.expireTime) / (60 * 1000);
        successMsg(`已发送，请于${expireMinutes}分钟内完成注册`);
        this.countSendWaitingTime();
      }
    },
    async verify(formName) {
      try {
        await this.$refs[formName].validate();
      } catch (e) {
        return;
      }
      const { email, verificationCode } = this.form;
      const resData = await this.apis.verify({ email, code: verificationCode });
      if (resData.success) {
        this.$emit('changeInfo', { email });
        this.$emit('stepForward');
        successMsg('校验通过');
      }
    },
    countSendWaitingTime() {
      this.sendWaitingTime = this.sendThrottlingTime;
      this.sendWaitingTimer = setInterval(() => {
        if (this.sendWaitingTime <= 0) {
          this.sendWaitingTime = 0;
          clearInterval(this.sendWaitingTimer);
          this.sendWaitingTimer = null;
          return;
        }
        this.sendWaitingTime -= msPerS;
      }, msPerS);
    }
  }
};
</script>

<style scoped lang="scss">
.register-email-container {
  &-back {
    width: fit-content;
    font-weight: 500;
    margin-bottom: 22px;
  }
}
</style>
